//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension Evidently {
    // MARK: Enums

    public enum ChangeDirectionEnum: String, CustomStringConvertible, Codable, _SotoSendable {
        case decrease = "DECREASE"
        case increase = "INCREASE"
        public var description: String { return self.rawValue }
    }

    public enum EventType: String, CustomStringConvertible, Codable, _SotoSendable {
        case awsEvidentlyCustom = "aws.evidently.custom"
        case awsEvidentlyEvaluation = "aws.evidently.evaluation"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentBaseStat: String, CustomStringConvertible, Codable, _SotoSendable {
        case mean = "Mean"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentReportName: String, CustomStringConvertible, Codable, _SotoSendable {
        case bayesianInference = "BayesianInference"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentResultRequestType: String, CustomStringConvertible, Codable, _SotoSendable {
        case baseStat = "BaseStat"
        case confidenceInterval = "ConfidenceInterval"
        case pValue = "PValue"
        case treatmentEffect = "TreatmentEffect"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentResultResponseType: String, CustomStringConvertible, Codable, _SotoSendable {
        case confidenceIntervalLowerBound = "ConfidenceIntervalLowerBound"
        case confidenceIntervalUpperBound = "ConfidenceIntervalUpperBound"
        case mean = "Mean"
        case pValue = "PValue"
        case treatmentEffect = "TreatmentEffect"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case cancelled = "CANCELLED"
        case completed = "COMPLETED"
        case created = "CREATED"
        case running = "RUNNING"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentStopDesiredState: String, CustomStringConvertible, Codable, _SotoSendable {
        case cancelled = "CANCELLED"
        case completed = "COMPLETED"
        public var description: String { return self.rawValue }
    }

    public enum ExperimentType: String, CustomStringConvertible, Codable, _SotoSendable {
        case awsEvidentlyOnlineab = "aws.evidently.onlineab"
        public var description: String { return self.rawValue }
    }

    public enum FeatureEvaluationStrategy: String, CustomStringConvertible, Codable, _SotoSendable {
        case allRules = "ALL_RULES"
        case defaultVariation = "DEFAULT_VARIATION"
        public var description: String { return self.rawValue }
    }

    public enum FeatureStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case available = "AVAILABLE"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum LaunchStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case cancelled = "CANCELLED"
        case completed = "COMPLETED"
        case created = "CREATED"
        case running = "RUNNING"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum LaunchStopDesiredState: String, CustomStringConvertible, Codable, _SotoSendable {
        case cancelled = "CANCELLED"
        case completed = "COMPLETED"
        public var description: String { return self.rawValue }
    }

    public enum LaunchType: String, CustomStringConvertible, Codable, _SotoSendable {
        case awsEvidentlySplits = "aws.evidently.splits"
        public var description: String { return self.rawValue }
    }

    public enum ProjectStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case available = "AVAILABLE"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum SegmentReferenceResourceType: String, CustomStringConvertible, Codable, _SotoSendable {
        case experiment = "EXPERIMENT"
        case launch = "LAUNCH"
        public var description: String { return self.rawValue }
    }

    public enum VariationValueType: String, CustomStringConvertible, Codable, _SotoSendable {
        case boolean = "BOOLEAN"
        case double = "DOUBLE"
        case long = "LONG"
        case string = "STRING"
        public var description: String { return self.rawValue }
    }

    public enum VariableValue: AWSEncodableShape & AWSDecodableShape, _SotoSendable {
        /// If this feature uses the Boolean variation type, this field contains the Boolean value of this variation.
        case boolValue(Bool)
        /// If this feature uses the double integer variation type, this field contains the double integer value of this variation.
        case doubleValue(Double)
        /// If this feature uses the long variation type, this field contains the long value of this variation.
        case longValue(Int64)
        /// If this feature uses the string variation type, this field contains the string value of this variation.
        case stringValue(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .boolValue:
                let value = try container.decode(Bool.self, forKey: .boolValue)
                self = .boolValue(value)
            case .doubleValue:
                let value = try container.decode(Double.self, forKey: .doubleValue)
                self = .doubleValue(value)
            case .longValue:
                let value = try container.decode(Int64.self, forKey: .longValue)
                self = .longValue(value)
            case .stringValue:
                let value = try container.decode(String.self, forKey: .stringValue)
                self = .stringValue(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .boolValue(let value):
                try container.encode(value, forKey: .boolValue)
            case .doubleValue(let value):
                try container.encode(value, forKey: .doubleValue)
            case .longValue(let value):
                try container.encode(value, forKey: .longValue)
            case .stringValue(let value):
                try container.encode(value, forKey: .stringValue)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case boolValue
            case doubleValue
            case longValue
            case stringValue
        }
    }

    // MARK: Shapes

    public struct BatchEvaluateFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name or ARN of the project that contains the feature being evaluated.
        public let project: String
        /// An array of structures, where each structure assigns a feature variation to one user session.
        public let requests: [EvaluationRequest]

        public init(project: String, requests: [EvaluationRequest]) {
            self.project = project
            self.requests = requests
        }

        public func validate(name: String) throws {
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.requests.forEach {
                try $0.validate(name: "\(name).requests[]")
            }
            try self.validate(self.requests, name: "requests", parent: name, max: 20)
            try self.validate(self.requests, name: "requests", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case requests
        }
    }

    public struct BatchEvaluateFeatureResponse: AWSDecodableShape {
        /// An array of structures, where each structure displays the results of one feature evaluation assignment to one user session.
        public let results: [EvaluationResult]?

        public init(results: [EvaluationResult]? = nil) {
            self.results = results
        }

        private enum CodingKeys: String, CodingKey {
            case results
        }
    }

    public struct CloudWatchLogsDestination: AWSDecodableShape {
        /// The name of the log group where the project stores evaluation events.
        public let logGroup: String?

        public init(logGroup: String? = nil) {
            self.logGroup = logGroup
        }

        private enum CodingKeys: String, CodingKey {
            case logGroup
        }
    }

    public struct CloudWatchLogsDestinationConfig: AWSEncodableShape {
        /// The name of the log group where the project stores evaluation events.
        public let logGroup: String?

        public init(logGroup: String? = nil) {
            self.logGroup = logGroup
        }

        public func validate(name: String) throws {
            try self.validate(self.logGroup, name: "logGroup", parent: name, max: 512)
            try self.validate(self.logGroup, name: "logGroup", parent: name, min: 1)
            try self.validate(self.logGroup, name: "logGroup", parent: name, pattern: "^[-a-zA-Z0-9._/]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case logGroup
        }
    }

    public struct CreateExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An optional description of the experiment.
        public let description: String?
        /// An array of structures that defines the metrics used for the experiment, and whether a higher or lower value for each metric is the goal.
        public let metricGoals: [MetricGoalConfig]
        /// A name for the new experiment.
        public let name: String
        /// A structure that contains the configuration of which variation to use as the "control" version. tThe "control" version is used for comparison with other variations. This structure also specifies how much experiment traffic is allocated to each variation.
        public let onlineAbConfig: OnlineAbConfig?
        /// The name or ARN of the project that you want to create the new experiment in.
        public let project: String
        /// When Evidently assigns a particular user session to an experiment, it must use a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt. If you omit randomizationSalt, Evidently uses the experiment name as the randomizationSalt.
        public let randomizationSalt: String?
        /// The portion of the available audience that you want to allocate to this experiment, in thousandths of a percent. The available audience is the total audience minus the audience that you have allocated to overrides or current launches of this feature. This is represented in thousandths of a percent. For example, specify 10,000 to allocate 10% of the available audience.
        public let samplingRate: Int64?
        /// Specifies an audience segment to use in the experiment. When a segment is used in an experiment, only user sessions that match the segment pattern are used in the experiment.
        public let segment: String?
        /// Assigns one or more tags (key-value pairs) to the experiment. Tags can help you organize and categorize your resources. You can also use them to scope user permissions by granting a user permission to access or change only resources with certain tag values. Tags don't have any semantic meaning to Amazon Web Services and are interpreted strictly as strings of characters.  You can associate as many as 50 tags with an experiment. For more information, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?
        /// An array of structures that describe the configuration of each feature variation used in the experiment.
        public let treatments: [TreatmentConfig]

        public init(description: String? = nil, metricGoals: [MetricGoalConfig], name: String, onlineAbConfig: OnlineAbConfig? = nil, project: String, randomizationSalt: String? = nil, samplingRate: Int64? = nil, segment: String? = nil, tags: [String: String]? = nil, treatments: [TreatmentConfig]) {
            self.description = description
            self.metricGoals = metricGoals
            self.name = name
            self.onlineAbConfig = onlineAbConfig
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.samplingRate = samplingRate
            self.segment = segment
            self.tags = tags
            self.treatments = treatments
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.metricGoals.forEach {
                try $0.validate(name: "\(name).metricGoals[]")
            }
            try self.validate(self.metricGoals, name: "metricGoals", parent: name, max: 3)
            try self.validate(self.metricGoals, name: "metricGoals", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.onlineAbConfig?.validate(name: "\(name).onlineAbConfig")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, max: 127)
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, pattern: ".*")
            try self.validate(self.samplingRate, name: "samplingRate", parent: name, max: 100_000)
            try self.validate(self.samplingRate, name: "samplingRate", parent: name, min: 0)
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.treatments.forEach {
                try $0.validate(name: "\(name).treatments[]")
            }
            try self.validate(self.treatments, name: "treatments", parent: name, max: 5)
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case metricGoals
            case name
            case onlineAbConfig
            case randomizationSalt
            case samplingRate
            case segment
            case tags
            case treatments
        }
    }

    public struct CreateExperimentResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the experiment that you created.
        public let experiment: Experiment

        public init(experiment: Experiment) {
            self.experiment = experiment
        }

        private enum CodingKeys: String, CodingKey {
            case experiment
        }
    }

    public struct CreateFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the variation to use as the default variation. The default variation is served to users who are not allocated to any ongoing launches or experiments of this feature. This variation must also be listed in the variations structure. If you omit defaultVariation, the first variation listed in the variations structure is used as the default variation.
        public let defaultVariation: String?
        /// An optional description of the feature.
        public let description: String?
        /// Specify users that should always be served a specific variation of a feature. Each user is specified by a key-value pair . For each key, specify a user by entering their user ID, account ID, or some other identifier. For the value, specify the name of the variation that they are to be served.
        public let entityOverrides: [String: String]?
        /// Specify ALL_RULES to activate the traffic allocation specified by any ongoing launches or experiments. Specify DEFAULT_VARIATION to serve the default variation to all users instead.
        public let evaluationStrategy: FeatureEvaluationStrategy?
        /// The name for the new feature.
        public let name: String
        /// The name or ARN of the project that is to contain the new feature.
        public let project: String
        /// Assigns one or more tags (key-value pairs) to the feature. Tags can help you organize and categorize your resources. You can also use them to scope user permissions by granting a user permission to access or change only resources with certain tag values. Tags don't have any semantic meaning to Amazon Web Services and are interpreted strictly as strings of characters.  You can associate as many as 50 tags with a feature. For more information, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?
        /// An array of structures that contain the configuration of the feature's different variations.
        public let variations: [VariationConfig]

        public init(defaultVariation: String? = nil, description: String? = nil, entityOverrides: [String: String]? = nil, evaluationStrategy: FeatureEvaluationStrategy? = nil, name: String, project: String, tags: [String: String]? = nil, variations: [VariationConfig]) {
            self.defaultVariation = defaultVariation
            self.description = description
            self.entityOverrides = entityOverrides
            self.evaluationStrategy = evaluationStrategy
            self.name = name
            self.project = project
            self.tags = tags
            self.variations = variations
        }

        public func validate(name: String) throws {
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, max: 127)
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, min: 1)
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.entityOverrides?.forEach {
                try validate($0.key, name: "entityOverrides.key", parent: name, max: 512)
                try validate($0.key, name: "entityOverrides.key", parent: name, min: 1)
                try validate($0.key, name: "entityOverrides.key", parent: name, pattern: ".*")
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, max: 127)
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            }
            try self.validate(self.entityOverrides, name: "entityOverrides", parent: name, max: 20)
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.variations.forEach {
                try $0.validate(name: "\(name).variations[]")
            }
            try self.validate(self.variations, name: "variations", parent: name, max: 5)
            try self.validate(self.variations, name: "variations", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case defaultVariation
            case description
            case entityOverrides
            case evaluationStrategy
            case name
            case tags
            case variations
        }
    }

    public struct CreateFeatureResponse: AWSDecodableShape {
        /// A structure that contains information about the new feature.
        public let feature: Feature?

        public init(feature: Feature? = nil) {
            self.feature = feature
        }

        private enum CodingKeys: String, CodingKey {
            case feature
        }
    }

    public struct CreateLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An optional description for the launch.
        public let description: String?
        /// An array of structures that contains the feature and variations that are to be used for the launch.
        public let groups: [LaunchGroupConfig]
        /// An array of structures that define the metrics that will be used to monitor  the launch performance.
        public let metricMonitors: [MetricMonitorConfig]?
        /// The name for the new launch.
        public let name: String
        /// The name or ARN of the project that you want to create the launch in.
        public let project: String
        /// When Evidently assigns a particular user session to a launch, it must use a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt. If you omit randomizationSalt, Evidently uses the launch name as the randomizationSalt.
        public let randomizationSalt: String?
        /// An array of structures that define the traffic allocation percentages among the feature variations during each step of the launch.
        public let scheduledSplitsConfig: ScheduledSplitsLaunchConfig?
        /// Assigns one or more tags (key-value pairs) to the launch. Tags can help you organize and categorize your resources. You can also use them to scope user permissions by granting a user permission to access or change only resources with certain tag values. Tags don't have any semantic meaning to Amazon Web Services and are interpreted strictly as strings of characters.  You can associate as many as 50 tags with a launch. For more information, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?

        public init(description: String? = nil, groups: [LaunchGroupConfig], metricMonitors: [MetricMonitorConfig]? = nil, name: String, project: String, randomizationSalt: String? = nil, scheduledSplitsConfig: ScheduledSplitsLaunchConfig? = nil, tags: [String: String]? = nil) {
            self.description = description
            self.groups = groups
            self.metricMonitors = metricMonitors
            self.name = name
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.scheduledSplitsConfig = scheduledSplitsConfig
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.groups.forEach {
                try $0.validate(name: "\(name).groups[]")
            }
            try self.validate(self.groups, name: "groups", parent: name, max: 5)
            try self.validate(self.groups, name: "groups", parent: name, min: 1)
            try self.metricMonitors?.forEach {
                try $0.validate(name: "\(name).metricMonitors[]")
            }
            try self.validate(self.metricMonitors, name: "metricMonitors", parent: name, max: 3)
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, max: 127)
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, pattern: ".*")
            try self.scheduledSplitsConfig?.validate(name: "\(name).scheduledSplitsConfig")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case groups
            case metricMonitors
            case name
            case randomizationSalt
            case scheduledSplitsConfig
            case tags
        }
    }

    public struct CreateLaunchResponse: AWSDecodableShape {
        /// A structure that contains the configuration of the launch that was created.
        public let launch: Launch

        public init(launch: Launch) {
            self.launch = launch
        }

        private enum CodingKeys: String, CodingKey {
            case launch
        }
    }

    public struct CreateProjectRequest: AWSEncodableShape {
        /// Use this parameter if the project will use client-side evaluation powered by AppConfig. Client-side evaluation allows your application to assign variations to user sessions locally instead of by calling the EvaluateFeature operation. This  mitigates the latency and availability risks that come with an API call. For more information,  see  Client-side evaluation - powered by AppConfig.  This parameter is a structure that contains information about the AppConfig application and environment that will be used as for client-side evaluation. To create a project that uses client-side evaluation, you must have the evidently:ExportProjectAsConfiguration permission.
        public let appConfigResource: ProjectAppConfigResourceConfig?
        /// A structure that contains information about where Evidently is to store evaluation events for longer term storage, if you choose to do so. If you choose not to store these events, Evidently deletes them after using them to produce metrics and other experiment results that you can view.
        public let dataDelivery: ProjectDataDeliveryConfig?
        /// An optional description of the project.
        public let description: String?
        /// The name for the project.
        public let name: String
        /// Assigns one or more tags (key-value pairs) to the project. Tags can help you organize and categorize your resources. You can also use them to scope user permissions by granting a user permission to access or change only resources with certain tag values. Tags don't have any semantic meaning to Amazon Web Services and are interpreted strictly as strings of characters.  You can associate as many as 50 tags with a project. For more information, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?

        public init(appConfigResource: ProjectAppConfigResourceConfig? = nil, dataDelivery: ProjectDataDeliveryConfig? = nil, description: String? = nil, name: String, tags: [String: String]? = nil) {
            self.appConfigResource = appConfigResource
            self.dataDelivery = dataDelivery
            self.description = description
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.appConfigResource?.validate(name: "\(name).appConfigResource")
            try self.dataDelivery?.validate(name: "\(name).dataDelivery")
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case appConfigResource
            case dataDelivery
            case description
            case name
            case tags
        }
    }

    public struct CreateProjectResponse: AWSDecodableShape {
        /// A structure that contains information about the created project.
        public let project: Project

        public init(project: Project) {
            self.project = project
        }

        private enum CodingKeys: String, CodingKey {
            case project
        }
    }

    public struct CreateSegmentRequest: AWSEncodableShape {
        /// An optional description for this segment.
        public let description: String?
        /// A name for the segment.
        public let name: String
        /// The pattern to use for the segment. For more information about pattern syntax,  see  Segment rule pattern syntax.
        public let pattern: String
        /// Assigns one or more tags (key-value pairs) to the segment. Tags can help you organize and categorize your resources. You can also use them to scope user permissions by granting a user permission to access or change only resources with certain tag values. Tags don't have any semantic meaning to Amazon Web Services and are interpreted strictly as strings of characters.  You can associate as many as 50 tags with a segment. For more information, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?

        public init(description: String? = nil, name: String, pattern: String, tags: [String: String]? = nil) {
            self.description = description
            self.name = name
            self.pattern = pattern
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.pattern, name: "pattern", parent: name, max: 1024)
            try self.validate(self.pattern, name: "pattern", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case name
            case pattern
            case tags
        }
    }

    public struct CreateSegmentResponse: AWSDecodableShape {
        /// A structure that contains the complete information about the segment that was just created.
        public let segment: Segment

        public init(segment: Segment) {
            self.segment = segment
        }

        private enum CodingKeys: String, CodingKey {
            case segment
        }
    }

    public struct DeleteExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the experiment to delete.
        public let experiment: String
        /// The name or ARN of the project that contains the experiment to delete.
        public let project: String

        public init(experiment: String, project: String) {
            self.experiment = experiment
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteExperimentResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "feature", location: .uri("feature")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the feature to delete.
        public let feature: String
        /// The name or ARN of the project that contains the feature to delete.
        public let project: String

        public init(feature: String, project: String) {
            self.feature = feature
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteFeatureResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "launch", location: .uri("launch")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the launch to delete.
        public let launch: String
        /// The name or ARN of the project that contains the launch to delete.
        public let project: String

        public init(launch: String, project: String) {
            self.launch = launch
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.launch, name: "launch", parent: name, max: 127)
            try self.validate(self.launch, name: "launch", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteLaunchResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteProjectRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name or ARN of the project to delete.
        public let project: String

        public init(project: String) {
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteProjectResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteSegmentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "segment", location: .uri("segment"))
        ]

        /// Specifies the segment to delete.
        public let segment: String

        public init(segment: String) {
            self.segment = segment
        }

        public func validate(name: String) throws {
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteSegmentResponse: AWSDecodableShape {
        public init() {}
    }

    public struct EvaluateFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "feature", location: .uri("feature")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An internal ID that represents a unique user of the application. This entityID is checked against any override rules assigned for this feature.
        public let entityId: String
        /// A JSON object of attributes that you can optionally pass in as part of the evaluation event sent to Evidently from the user session. Evidently can use  this value to match user sessions with defined audience segments. For more information, see Use segments to focus your  audience.  If you include this parameter, the value must be a JSON object. A JSON array is not supported.
        public let evaluationContext: String?
        /// The name of the feature being evaluated.
        public let feature: String
        /// The name or ARN of the project that contains this feature.
        public let project: String

        public init(entityId: String, evaluationContext: String? = nil, feature: String, project: String) {
            self.entityId = entityId
            self.evaluationContext = evaluationContext
            self.feature = feature
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.entityId, name: "entityId", parent: name, max: 512)
            try self.validate(self.entityId, name: "entityId", parent: name, min: 1)
            try self.validate(self.entityId, name: "entityId", parent: name, pattern: ".*")
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: String, CodingKey {
            case entityId
            case evaluationContext
        }
    }

    public struct EvaluateFeatureResponse: AWSDecodableShape {
        /// If this user was assigned to a launch or experiment, this field lists the launch or experiment name.
        public let details: String?
        /// Specifies the reason that the user session was assigned this variation. Possible values include DEFAULT, meaning the user was served the default variation; LAUNCH_RULE_MATCH, if the user session was enrolled in a launch; EXPERIMENT_RULE_MATCH, if the user session was enrolled in an experiment; or ENTITY_OVERRIDES_MATCH, if the user's entityId matches an override rule.
        public let reason: String?
        /// The value assigned to this variation to differentiate it from the other variations of this feature.
        public let value: VariableValue?
        /// The name of the variation that was served to the user session.
        public let variation: String?

        public init(details: String? = nil, reason: String? = nil, value: VariableValue? = nil, variation: String? = nil) {
            self.details = details
            self.reason = reason
            self.value = value
            self.variation = variation
        }

        private enum CodingKeys: String, CodingKey {
            case details
            case reason
            case value
            case variation
        }
    }

    public struct EvaluationRequest: AWSEncodableShape {
        /// An internal ID that represents a unique user session of the application. This entityID is checked against any override rules assigned for this feature.
        public let entityId: String
        /// A JSON block of attributes that you can optionally pass in. This JSON block is included in the evaluation events sent to Evidently from the user session.
        public let evaluationContext: String?
        /// The name of the feature being evaluated.
        public let feature: String

        public init(entityId: String, evaluationContext: String? = nil, feature: String) {
            self.entityId = entityId
            self.evaluationContext = evaluationContext
            self.feature = feature
        }

        public func validate(name: String) throws {
            try self.validate(self.entityId, name: "entityId", parent: name, max: 512)
            try self.validate(self.entityId, name: "entityId", parent: name, min: 1)
            try self.validate(self.entityId, name: "entityId", parent: name, pattern: ".*")
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case entityId
            case evaluationContext
            case feature
        }
    }

    public struct EvaluationResult: AWSDecodableShape {
        /// If this user was assigned to a launch or experiment, this field lists the launch or experiment name.
        public let details: String?
        /// An internal ID that represents a unique user session of the application.
        public let entityId: String
        /// The name of the feature being evaluated.
        public let feature: String
        /// The name or ARN of the project that contains the feature being evaluated.
        public let project: String?
        /// Specifies the reason that the user session was assigned this variation. Possible values include DEFAULT, meaning the user was served the default variation; LAUNCH_RULE_MATCH, if the user session was enrolled in a launch; or EXPERIMENT_RULE_MATCH, if the user session was enrolled in an experiment.
        public let reason: String?
        /// The value assigned to this variation to differentiate it from the other variations of this feature.
        public let value: VariableValue?
        /// The name of the variation that was served to the user session.
        public let variation: String?

        public init(details: String? = nil, entityId: String, feature: String, project: String? = nil, reason: String? = nil, value: VariableValue? = nil, variation: String? = nil) {
            self.details = details
            self.entityId = entityId
            self.feature = feature
            self.project = project
            self.reason = reason
            self.value = value
            self.variation = variation
        }

        private enum CodingKeys: String, CodingKey {
            case details
            case entityId
            case feature
            case project
            case reason
            case value
            case variation
        }
    }

    public struct EvaluationRule: AWSDecodableShape {
        /// The name of the experiment or launch.
        public let name: String?
        /// This value is aws.evidently.splits if this is an evaluation rule for a launch, and it is aws.evidently.onlineab if this is an evaluation rule for an experiment.
        public let type: String

        public init(name: String? = nil, type: String) {
            self.name = name
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case type
        }
    }

    public struct Event: AWSEncodableShape {
        /// The event data.
        public let data: String
        /// The timestamp of the event.
        public let timestamp: Date
        ///  aws.evidently.evaluation specifies an evaluation event, which determines which feature variation that a user sees. aws.evidently.custom specifies a custom event, which generates metrics from user actions such as clicks and checkouts.
        public let type: EventType

        public init(data: String, timestamp: Date, type: EventType) {
            self.data = data
            self.timestamp = timestamp
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case data
            case timestamp
            case type
        }
    }

    public struct Experiment: AWSDecodableShape {
        /// The ARN of the experiment.
        public let arn: String
        /// The date and time that the experiment is first created.
        public let createdTime: Date
        /// A description of the experiment.
        public let description: String?
        /// A structure that contains the date and time that the experiment started and ended.
        public let execution: ExperimentExecution?
        /// The date and time that the experiment was most recently updated.
        public let lastUpdatedTime: Date
        /// An array of structures that defines the metrics used for the experiment, and whether a higher or lower value for each metric is the goal.
        public let metricGoals: [MetricGoal]?
        /// The name of the experiment.
        public let name: String
        /// A structure that contains the configuration of which variation to use as the "control" version. The "control" version is used for comparison with other variations. This structure also specifies how much experiment traffic is allocated to each variation.
        public let onlineAbDefinition: OnlineAbDefinition?
        /// The name or ARN of the project that contains this experiment.
        public let project: String?
        /// This value is used when Evidently assigns a particular user session to the experiment. It helps create a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt.
        public let randomizationSalt: String?
        /// In thousandths of a percent, the amount of the available audience that is allocated to this experiment.  The available audience is the total audience minus the audience that you have allocated to overrides or current launches of this feature. This is represented in thousandths of a percent, so a value of 10,000 is 10% of the available audience.
        public let samplingRate: Int64?
        /// A structure that contains the time and date that Evidently completed the analysis of the experiment.
        public let schedule: ExperimentSchedule?
        /// The audience segment being used for the experiment, if a segment is being used.
        public let segment: String?
        /// The current state of the experiment.
        public let status: ExperimentStatus
        /// If the experiment was stopped, this is the string that was entered by the person who  stopped the experiment, to explain why it was stopped.
        public let statusReason: String?
        /// The list of tag keys and values associated with this experiment.
        public let tags: [String: String]?
        /// An array of structures that describe the configuration of each feature variation used in the experiment.
        public let treatments: [Treatment]?
        /// The type of this experiment. Currently, this value must be aws.experiment.onlineab.
        public let type: ExperimentType

        public init(arn: String, createdTime: Date, description: String? = nil, execution: ExperimentExecution? = nil, lastUpdatedTime: Date, metricGoals: [MetricGoal]? = nil, name: String, onlineAbDefinition: OnlineAbDefinition? = nil, project: String? = nil, randomizationSalt: String? = nil, samplingRate: Int64? = nil, schedule: ExperimentSchedule? = nil, segment: String? = nil, status: ExperimentStatus, statusReason: String? = nil, tags: [String: String]? = nil, treatments: [Treatment]? = nil, type: ExperimentType) {
            self.arn = arn
            self.createdTime = createdTime
            self.description = description
            self.execution = execution
            self.lastUpdatedTime = lastUpdatedTime
            self.metricGoals = metricGoals
            self.name = name
            self.onlineAbDefinition = onlineAbDefinition
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.samplingRate = samplingRate
            self.schedule = schedule
            self.segment = segment
            self.status = status
            self.statusReason = statusReason
            self.tags = tags
            self.treatments = treatments
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdTime
            case description
            case execution
            case lastUpdatedTime
            case metricGoals
            case name
            case onlineAbDefinition
            case project
            case randomizationSalt
            case samplingRate
            case schedule
            case segment
            case status
            case statusReason
            case tags
            case treatments
            case type
        }
    }

    public struct ExperimentExecution: AWSDecodableShape {
        /// The date and time that the experiment ended.
        public let endedTime: Date?
        /// The date and time that the experiment started.
        public let startedTime: Date?

        public init(endedTime: Date? = nil, startedTime: Date? = nil) {
            self.endedTime = endedTime
            self.startedTime = startedTime
        }

        private enum CodingKeys: String, CodingKey {
            case endedTime
            case startedTime
        }
    }

    public struct ExperimentReport: AWSDecodableShape {
        /// The content of the report.
        public let content: String?
        /// The name of the metric that is analyzed in this experiment report.
        public let metricName: String?
        /// The type of analysis used for this report.
        public let reportName: ExperimentReportName?
        /// The name of the variation that this report pertains to.
        public let treatmentName: String?

        public init(content: String? = nil, metricName: String? = nil, reportName: ExperimentReportName? = nil, treatmentName: String? = nil) {
            self.content = content
            self.metricName = metricName
            self.reportName = reportName
            self.treatmentName = treatmentName
        }

        private enum CodingKeys: String, CodingKey {
            case content
            case metricName
            case reportName
            case treatmentName
        }
    }

    public struct ExperimentResultsData: AWSDecodableShape {
        /// The name of the metric.
        public let metricName: String?
        /// The experiment statistic that these results pertain to.
        public let resultStat: ExperimentResultResponseType?
        /// The treatment, or variation, that returned the values in this structure.
        public let treatmentName: String?
        /// The values for the metricName that were recorded in the experiment.
        public let values: [Double]?

        public init(metricName: String? = nil, resultStat: ExperimentResultResponseType? = nil, treatmentName: String? = nil, values: [Double]? = nil) {
            self.metricName = metricName
            self.resultStat = resultStat
            self.treatmentName = treatmentName
            self.values = values
        }

        private enum CodingKeys: String, CodingKey {
            case metricName
            case resultStat
            case treatmentName
            case values
        }
    }

    public struct ExperimentSchedule: AWSDecodableShape {
        /// The time and date that Evidently completed the analysis of the experiment.
        public let analysisCompleteTime: Date?

        public init(analysisCompleteTime: Date? = nil) {
            self.analysisCompleteTime = analysisCompleteTime
        }

        private enum CodingKeys: String, CodingKey {
            case analysisCompleteTime
        }
    }

    public struct Feature: AWSDecodableShape {
        /// The ARN of the feature.
        public let arn: String
        /// The date and time that the feature is created.
        public let createdTime: Date
        /// The name of the variation that is used as the default variation. The default variation is served to users who are not allocated to any ongoing launches or experiments of this feature. This variation must also be listed in the variations structure. If you omit defaultVariation, the first variation listed in the variations structure is used as the default variation.
        public let defaultVariation: String?
        /// The description of the feature.
        public let description: String?
        /// A set of key-value pairs  that specify users who should always be served a specific variation of a feature. Each key specifies a user using their user ID, account ID, or some other identifier. The value specifies the name of the variation that the user is to be served. For the override to be successful, the value of the key must match the entityId used  in the EvaluateFeature operation.
        public let entityOverrides: [String: String]?
        /// An array of structures that define the evaluation rules for the feature.
        public let evaluationRules: [EvaluationRule]?
        /// If this value is ALL_RULES, the traffic allocation specified by any ongoing launches or experiments is being used. If this is DEFAULT_VARIATION, the default variation is being served to all users.
        public let evaluationStrategy: FeatureEvaluationStrategy
        /// The date and time that the feature was most recently updated.
        public let lastUpdatedTime: Date
        /// The name of the feature.
        public let name: String
        /// The name or ARN of the project that contains the feature.
        public let project: String?
        /// The current state of the feature.
        public let status: FeatureStatus
        /// The list of tag keys and values associated with this feature.
        public let tags: [String: String]?
        /// Defines the type of value used to define the different feature variations.  For more information, see Variation types
        public let valueType: VariationValueType
        /// An array of structures that contain the configuration of the feature's different variations.
        public let variations: [Variation]

        public init(arn: String, createdTime: Date, defaultVariation: String? = nil, description: String? = nil, entityOverrides: [String: String]? = nil, evaluationRules: [EvaluationRule]? = nil, evaluationStrategy: FeatureEvaluationStrategy, lastUpdatedTime: Date, name: String, project: String? = nil, status: FeatureStatus, tags: [String: String]? = nil, valueType: VariationValueType, variations: [Variation]) {
            self.arn = arn
            self.createdTime = createdTime
            self.defaultVariation = defaultVariation
            self.description = description
            self.entityOverrides = entityOverrides
            self.evaluationRules = evaluationRules
            self.evaluationStrategy = evaluationStrategy
            self.lastUpdatedTime = lastUpdatedTime
            self.name = name
            self.project = project
            self.status = status
            self.tags = tags
            self.valueType = valueType
            self.variations = variations
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdTime
            case defaultVariation
            case description
            case entityOverrides
            case evaluationRules
            case evaluationStrategy
            case lastUpdatedTime
            case name
            case project
            case status
            case tags
            case valueType
            case variations
        }
    }

    public struct FeatureSummary: AWSDecodableShape {
        /// The ARN of the feature.
        public let arn: String
        /// The date and time that the feature is created.
        public let createdTime: Date
        /// The name of the variation that is used as the default variation. The default variation is served to users who are not allocated to any ongoing launches or experiments of this feature.
        public let defaultVariation: String?
        /// An array of structures that define
        public let evaluationRules: [EvaluationRule]?
        /// If this value is ALL_RULES, the traffic allocation specified by any ongoing launches or experiments is being used. If this is DEFAULT_VARIATION, the default variation is being served to all users.
        public let evaluationStrategy: FeatureEvaluationStrategy
        /// The date and time that the feature was most recently updated.
        public let lastUpdatedTime: Date
        /// The name of the feature.
        public let name: String
        /// The name or ARN of the project that contains the feature.
        public let project: String?
        /// The current state of the feature.
        public let status: FeatureStatus
        /// The list of tag keys and values associated with this feature.
        public let tags: [String: String]?

        public init(arn: String, createdTime: Date, defaultVariation: String? = nil, evaluationRules: [EvaluationRule]? = nil, evaluationStrategy: FeatureEvaluationStrategy, lastUpdatedTime: Date, name: String, project: String? = nil, status: FeatureStatus, tags: [String: String]? = nil) {
            self.arn = arn
            self.createdTime = createdTime
            self.defaultVariation = defaultVariation
            self.evaluationRules = evaluationRules
            self.evaluationStrategy = evaluationStrategy
            self.lastUpdatedTime = lastUpdatedTime
            self.name = name
            self.project = project
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdTime
            case defaultVariation
            case evaluationRules
            case evaluationStrategy
            case lastUpdatedTime
            case name
            case project
            case status
            case tags
        }
    }

    public struct GetExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the experiment that you want to see the details of.
        public let experiment: String
        /// The name or ARN of the project that contains the experiment.
        public let project: String

        public init(experiment: String, project: String) {
            self.experiment = experiment
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetExperimentResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the experiment.
        public let experiment: Experiment?

        public init(experiment: Experiment? = nil) {
            self.experiment = experiment
        }

        private enum CodingKeys: String, CodingKey {
            case experiment
        }
    }

    public struct GetExperimentResultsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The statistic used to calculate experiment results. Currently the only valid value is mean,  which uses the mean of the collected values as the statistic.
        public let baseStat: ExperimentBaseStat?
        /// The date and time that the experiment ended, if it is completed. This must be no longer than 30 days  after the experiment start time.
        public let endTime: Date?
        /// The name of the experiment to retrieve the results of.
        public let experiment: String
        /// The names of the experiment metrics that you want to see the results of.
        public let metricNames: [String]
        /// In seconds, the amount of time to aggregate results together.
        public let period: Int64?
        /// The name or ARN of the project that contains the experiment that you want to see the results of.
        public let project: String
        /// The names of the report types that you want to see. Currently, BayesianInference is the only valid value.
        public let reportNames: [ExperimentReportName]?
        /// The statistics that you want to see in the returned results.    PValue specifies to use p-values for the results. A p-value is used in hypothesis testing to measure how often you are willing to make a mistake in rejecting the null hypothesis. A general practice is to reject the null hypothesis and declare that the results are statistically significant when the p-value is less than 0.05.    ConfidenceInterval specifies a confidence interval for the results. The confidence interval represents the range of values for the chosen metric that is likely to contain the true difference between the baseStat of a variation and the baseline. Evidently returns the 95% confidence interval.     TreatmentEffect is the difference in the statistic specified by the baseStat parameter between each variation and the default variation.     BaseStat returns the statistical values collected for the metric for each variation. The statistic uses the same statistic specified in the baseStat parameter. Therefore, if baseStat is mean, this returns the mean of the values collected for each variation.
        public let resultStats: [ExperimentResultRequestType]?
        /// The date and time that the experiment started.
        public let startTime: Date?
        /// The names of the experiment treatments that you want to see the results for.
        public let treatmentNames: [String]

        public init(baseStat: ExperimentBaseStat? = nil, endTime: Date? = nil, experiment: String, metricNames: [String], period: Int64? = nil, project: String, reportNames: [ExperimentReportName]? = nil, resultStats: [ExperimentResultRequestType]? = nil, startTime: Date? = nil, treatmentNames: [String]) {
            self.baseStat = baseStat
            self.endTime = endTime
            self.experiment = experiment
            self.metricNames = metricNames
            self.period = period
            self.project = project
            self.reportNames = reportNames
            self.resultStats = resultStats
            self.startTime = startTime
            self.treatmentNames = treatmentNames
        }

        public func validate(name: String) throws {
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.metricNames.forEach {
                try validate($0, name: "metricNames[]", parent: name, max: 255)
                try validate($0, name: "metricNames[]", parent: name, min: 1)
                try validate($0, name: "metricNames[]", parent: name, pattern: "^[\\S]+$")
            }
            try self.validate(self.metricNames, name: "metricNames", parent: name, max: 1)
            try self.validate(self.metricNames, name: "metricNames", parent: name, min: 1)
            try self.validate(self.period, name: "period", parent: name, max: 90000)
            try self.validate(self.period, name: "period", parent: name, min: 300)
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.reportNames, name: "reportNames", parent: name, max: 5)
            try self.validate(self.resultStats, name: "resultStats", parent: name, max: 5)
            try self.treatmentNames.forEach {
                try validate($0, name: "treatmentNames[]", parent: name, max: 127)
                try validate($0, name: "treatmentNames[]", parent: name, min: 1)
                try validate($0, name: "treatmentNames[]", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            }
            try self.validate(self.treatmentNames, name: "treatmentNames", parent: name, max: 5)
            try self.validate(self.treatmentNames, name: "treatmentNames", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case baseStat
            case endTime
            case metricNames
            case period
            case reportNames
            case resultStats
            case startTime
            case treatmentNames
        }
    }

    public struct GetExperimentResultsResponse: AWSDecodableShape {
        /// If the experiment doesn't yet have enough events to provide valid results, this  field is returned with the message Not enough events to generate results. If there are  enough events to provide valid results, this field is not returned.
        public let details: String?
        /// An array of structures that include the reports that you requested.
        public let reports: [ExperimentReport]?
        /// An array of structures that include experiment results including metric names and values.
        public let resultsData: [ExperimentResultsData]?
        /// The timestamps of each result returned.
        public let timestamps: [Date]?

        public init(details: String? = nil, reports: [ExperimentReport]? = nil, resultsData: [ExperimentResultsData]? = nil, timestamps: [Date]? = nil) {
            self.details = details
            self.reports = reports
            self.resultsData = resultsData
            self.timestamps = timestamps
        }

        private enum CodingKeys: String, CodingKey {
            case details
            case reports
            case resultsData
            case timestamps
        }
    }

    public struct GetFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "feature", location: .uri("feature")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the feature that you want to retrieve information for.
        public let feature: String
        /// The name or ARN of the project that contains the feature.
        public let project: String

        public init(feature: String, project: String) {
            self.feature = feature
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetFeatureResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the feature.
        public let feature: Feature

        public init(feature: Feature) {
            self.feature = feature
        }

        private enum CodingKeys: String, CodingKey {
            case feature
        }
    }

    public struct GetLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "launch", location: .uri("launch")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the launch that you want to see the details of.
        public let launch: String
        /// The name or ARN of the project that contains the launch.
        public let project: String

        public init(launch: String, project: String) {
            self.launch = launch
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.launch, name: "launch", parent: name, max: 127)
            try self.validate(self.launch, name: "launch", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetLaunchResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the launch.
        public let launch: Launch?

        public init(launch: Launch? = nil) {
            self.launch = launch
        }

        private enum CodingKeys: String, CodingKey {
            case launch
        }
    }

    public struct GetProjectRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name or ARN of the project that you want to see the details of.
        public let project: String

        public init(project: String) {
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetProjectResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the project.
        public let project: Project

        public init(project: Project) {
            self.project = project
        }

        private enum CodingKeys: String, CodingKey {
            case project
        }
    }

    public struct GetSegmentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "segment", location: .uri("segment"))
        ]

        /// The ARN of the segment to return information for.
        public let segment: String

        public init(segment: String) {
            self.segment = segment
        }

        public func validate(name: String) throws {
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetSegmentResponse: AWSDecodableShape {
        /// A structure that contains the complete information about the segment.
        public let segment: Segment

        public init(segment: Segment) {
            self.segment = segment
        }

        private enum CodingKeys: String, CodingKey {
            case segment
        }
    }

    public struct Launch: AWSDecodableShape {
        /// The ARN of the launch.
        public let arn: String
        /// The date and time that the launch is created.
        public let createdTime: Date
        /// The description of the launch.
        public let description: String?
        /// A structure that contains information about the start and end times of the launch.
        public let execution: LaunchExecution?
        /// An array of structures that define the feature variations that are being used in the launch.
        public let groups: [LaunchGroup]?
        /// The date and time that the launch was most recently updated.
        public let lastUpdatedTime: Date
        /// An array of structures that define the metrics that are being used to monitor the launch performance.
        public let metricMonitors: [MetricMonitor]?
        /// The name of the launch.
        public let name: String
        /// The name or ARN of the project that contains the launch.
        public let project: String?
        /// This value is used when Evidently assigns a particular user session to the launch, to help create a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt.
        public let randomizationSalt: String?
        /// An array of structures that define the traffic allocation percentages among the feature variations during each step of the launch.
        public let scheduledSplitsDefinition: ScheduledSplitsLaunchDefinition?
        /// The current state of the launch.
        public let status: LaunchStatus
        /// If the launch was stopped, this is the string that was entered by the person who  stopped the launch, to explain why it was stopped.
        public let statusReason: String?
        /// The list of tag keys and values associated with this launch.
        public let tags: [String: String]?
        /// The type of launch.
        public let type: LaunchType

        public init(arn: String, createdTime: Date, description: String? = nil, execution: LaunchExecution? = nil, groups: [LaunchGroup]? = nil, lastUpdatedTime: Date, metricMonitors: [MetricMonitor]? = nil, name: String, project: String? = nil, randomizationSalt: String? = nil, scheduledSplitsDefinition: ScheduledSplitsLaunchDefinition? = nil, status: LaunchStatus, statusReason: String? = nil, tags: [String: String]? = nil, type: LaunchType) {
            self.arn = arn
            self.createdTime = createdTime
            self.description = description
            self.execution = execution
            self.groups = groups
            self.lastUpdatedTime = lastUpdatedTime
            self.metricMonitors = metricMonitors
            self.name = name
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.scheduledSplitsDefinition = scheduledSplitsDefinition
            self.status = status
            self.statusReason = statusReason
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdTime
            case description
            case execution
            case groups
            case lastUpdatedTime
            case metricMonitors
            case name
            case project
            case randomizationSalt
            case scheduledSplitsDefinition
            case status
            case statusReason
            case tags
            case type
        }
    }

    public struct LaunchExecution: AWSDecodableShape {
        /// The date and time that the launch ended.
        public let endedTime: Date?
        /// The date and time that the launch started.
        public let startedTime: Date?

        public init(endedTime: Date? = nil, startedTime: Date? = nil) {
            self.endedTime = endedTime
            self.startedTime = startedTime
        }

        private enum CodingKeys: String, CodingKey {
            case endedTime
            case startedTime
        }
    }

    public struct LaunchGroup: AWSDecodableShape {
        /// A description of the launch group.
        public let description: String?
        /// The feature variation for this launch group. This is a key-value pair.
        public let featureVariations: [String: String]
        /// The name of the launch group.
        public let name: String

        public init(description: String? = nil, featureVariations: [String: String], name: String) {
            self.description = description
            self.featureVariations = featureVariations
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case featureVariations
            case name
        }
    }

    public struct LaunchGroupConfig: AWSEncodableShape {
        /// A description of the launch group.
        public let description: String?
        /// The feature that this launch is using.
        public let feature: String
        /// A name for this launch group.
        public let name: String
        /// The feature variation to use for this launch group.
        public let variation: String

        public init(description: String? = nil, feature: String, name: String, variation: String) {
            self.description = description
            self.feature = feature
            self.name = name
            self.variation = variation
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.variation, name: "variation", parent: name, max: 127)
            try self.validate(self.variation, name: "variation", parent: name, min: 1)
            try self.validate(self.variation, name: "variation", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case feature
            case name
            case variation
        }
    }

    public struct ListExperimentsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "project", location: .uri("project")),
            AWSMemberEncoding(label: "status", location: .querystring("status"))
        ]

        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListExperiments operation.
        public let nextToken: String?
        /// The name or ARN of the project to return the experiment list from.
        public let project: String
        /// Use this optional parameter to limit the returned results to only the experiments with the status that you specify here.
        public let status: ExperimentStatus?

        public init(maxResults: Int? = nil, nextToken: String? = nil, project: String, status: ExperimentStatus? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.project = project
            self.status = status
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListExperimentsResponse: AWSDecodableShape {
        /// An array of structures that contain the configuration details of the experiments in the specified project.
        public let experiments: [Experiment]?
        /// The token to use in a subsequent ListExperiments operation to return the next set of results.
        public let nextToken: String?

        public init(experiments: [Experiment]? = nil, nextToken: String? = nil) {
            self.experiments = experiments
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case experiments
            case nextToken
        }
    }

    public struct ListFeaturesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListFeatures operation.
        public let nextToken: String?
        /// The name or ARN of the project to return the feature list from.
        public let project: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, project: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListFeaturesResponse: AWSDecodableShape {
        /// An array of structures that contain the configuration details of the features in the specified project.
        public let features: [FeatureSummary]?
        /// The token to use in a subsequent ListFeatures operation to return the next set of results.
        public let nextToken: String?

        public init(features: [FeatureSummary]? = nil, nextToken: String? = nil) {
            self.features = features
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case features
            case nextToken
        }
    }

    public struct ListLaunchesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "project", location: .uri("project")),
            AWSMemberEncoding(label: "status", location: .querystring("status"))
        ]

        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListLaunches operation.
        public let nextToken: String?
        /// The name or ARN of the project to return the launch list from.
        public let project: String
        /// Use this optional parameter to limit the returned results to only the launches with the status that you specify here.
        public let status: LaunchStatus?

        public init(maxResults: Int? = nil, nextToken: String? = nil, project: String, status: LaunchStatus? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.project = project
            self.status = status
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListLaunchesResponse: AWSDecodableShape {
        /// An array of structures that contain the configuration details of the launches in the specified project.
        public let launches: [Launch]?
        /// The token to use in a subsequent ListLaunches operation to return the next set of results.
        public let nextToken: String?

        public init(launches: [Launch]? = nil, nextToken: String? = nil) {
            self.launches = launches
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case launches
            case nextToken
        }
    }

    public struct ListProjectsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListProjects operation.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListProjectsResponse: AWSDecodableShape {
        /// The token to use in a subsequent ListProjects operation to return the next set of results.
        public let nextToken: String?
        /// An array of structures that contain the configuration details of the projects in the Region.
        public let projects: [ProjectSummary]?

        public init(nextToken: String? = nil, projects: [ProjectSummary]? = nil) {
            self.nextToken = nextToken
            self.projects = projects
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case projects
        }
    }

    public struct ListSegmentReferencesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "segment", location: .uri("segment")),
            AWSMemberEncoding(label: "type", location: .querystring("type"))
        ]

        /// The maximum number of results to include in the response. If you omit this, the default of 50 is used.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListSegmentReferences operation.
        public let nextToken: String?
        /// The ARN of the segment that you want to view information for.
        public let segment: String
        /// Specifies whether to return information about launches or experiments that use this segment.
        public let type: SegmentReferenceResourceType

        public init(maxResults: Int? = nil, nextToken: String? = nil, segment: String, type: SegmentReferenceResourceType) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.segment = segment
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSegmentReferencesResponse: AWSDecodableShape {
        /// The token to use in a subsequent ListSegmentReferences operation to return the next set of results.
        public let nextToken: String?
        /// An array of structures, where each structure contains information about one experiment or launch that uses this segment.
        public let referencedBy: [RefResource]?

        public init(nextToken: String? = nil, referencedBy: [RefResource]? = nil) {
            self.nextToken = nextToken
            self.referencedBy = referencedBy
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case referencedBy
        }
    }

    public struct ListSegmentsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The maximum number of results to include in the response. If you omit this, the default of 50 is used.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous  ListSegments operation.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSegmentsResponse: AWSDecodableShape {
        /// The token to use in a subsequent ListSegments operation to return the next set of results.
        public let nextToken: String?
        /// An array of structures that contain information about the segments in this Region.
        public let segments: [Segment]?

        public init(nextToken: String? = nil, segments: [Segment]? = nil) {
            self.nextToken = nextToken
            self.segments = segments
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case segments
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// The ARN of the resource that you want to see the tags of.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The list of tag keys and values associated with the resource you specified.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct MetricDefinition: AWSDecodableShape {
        /// The entity, such as a user or session, that does an action that causes a metric value to be recorded.
        public let entityIdKey: String?
        /// The EventBridge event pattern that defines how the metric is recorded. For more information about EventBridge event patterns, see  Amazon EventBridge event patterns.
        public let eventPattern: String?
        /// The name of the metric.
        public let name: String?
        /// The label for the units that the metric is measuring.
        public let unitLabel: String?
        /// The value that is tracked to produce the metric.
        public let valueKey: String?

        public init(entityIdKey: String? = nil, eventPattern: String? = nil, name: String? = nil, unitLabel: String? = nil, valueKey: String? = nil) {
            self.entityIdKey = entityIdKey
            self.eventPattern = eventPattern
            self.name = name
            self.unitLabel = unitLabel
            self.valueKey = valueKey
        }

        private enum CodingKeys: String, CodingKey {
            case entityIdKey
            case eventPattern
            case name
            case unitLabel
            case valueKey
        }
    }

    public struct MetricDefinitionConfig: AWSEncodableShape {
        /// The entity, such as a user or session, that does an action that causes a metric value to be recorded. An example is userDetails.userID.
        public let entityIdKey: String
        /// The EventBridge event pattern that defines how the metric is recorded. For more information about EventBridge event patterns, see  Amazon EventBridge event patterns.
        public let eventPattern: String?
        /// A name for the metric.
        public let name: String
        /// A label for the units that the metric is measuring.
        public let unitLabel: String?
        /// The value that is tracked to produce the metric.
        public let valueKey: String

        public init(entityIdKey: String, eventPattern: String? = nil, name: String, unitLabel: String? = nil, valueKey: String) {
            self.entityIdKey = entityIdKey
            self.eventPattern = eventPattern
            self.name = name
            self.unitLabel = unitLabel
            self.valueKey = valueKey
        }

        public func validate(name: String) throws {
            try self.validate(self.entityIdKey, name: "entityIdKey", parent: name, max: 256)
            try self.validate(self.entityIdKey, name: "entityIdKey", parent: name, min: 1)
            try self.validate(self.entityIdKey, name: "entityIdKey", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[\\S]+$")
            try self.validate(self.unitLabel, name: "unitLabel", parent: name, max: 256)
            try self.validate(self.unitLabel, name: "unitLabel", parent: name, min: 1)
            try self.validate(self.unitLabel, name: "unitLabel", parent: name, pattern: ".*")
            try self.validate(self.valueKey, name: "valueKey", parent: name, max: 256)
            try self.validate(self.valueKey, name: "valueKey", parent: name, min: 1)
            try self.validate(self.valueKey, name: "valueKey", parent: name, pattern: ".*")
        }

        private enum CodingKeys: String, CodingKey {
            case entityIdKey
            case eventPattern
            case name
            case unitLabel
            case valueKey
        }
    }

    public struct MetricGoal: AWSDecodableShape {
        ///  INCREASE means that a variation with a higher number for this metric is performing  better.  DECREASE means that a variation with a lower number for this metric is performing  better.
        public let desiredChange: ChangeDirectionEnum?
        /// A structure that contains details about the metric.
        public let metricDefinition: MetricDefinition

        public init(desiredChange: ChangeDirectionEnum? = nil, metricDefinition: MetricDefinition) {
            self.desiredChange = desiredChange
            self.metricDefinition = metricDefinition
        }

        private enum CodingKeys: String, CodingKey {
            case desiredChange
            case metricDefinition
        }
    }

    public struct MetricGoalConfig: AWSEncodableShape {
        ///  INCREASE means that a variation with a higher number for this metric is performing  better.  DECREASE means that a variation with a lower number for this metric is performing  better.
        public let desiredChange: ChangeDirectionEnum?
        /// A structure that contains details about the metric.
        public let metricDefinition: MetricDefinitionConfig

        public init(desiredChange: ChangeDirectionEnum? = nil, metricDefinition: MetricDefinitionConfig) {
            self.desiredChange = desiredChange
            self.metricDefinition = metricDefinition
        }

        public func validate(name: String) throws {
            try self.metricDefinition.validate(name: "\(name).metricDefinition")
        }

        private enum CodingKeys: String, CodingKey {
            case desiredChange
            case metricDefinition
        }
    }

    public struct MetricMonitor: AWSDecodableShape {
        /// A structure that defines the metric.
        public let metricDefinition: MetricDefinition

        public init(metricDefinition: MetricDefinition) {
            self.metricDefinition = metricDefinition
        }

        private enum CodingKeys: String, CodingKey {
            case metricDefinition
        }
    }

    public struct MetricMonitorConfig: AWSEncodableShape {
        /// A structure that defines the metric.
        public let metricDefinition: MetricDefinitionConfig

        public init(metricDefinition: MetricDefinitionConfig) {
            self.metricDefinition = metricDefinition
        }

        public func validate(name: String) throws {
            try self.metricDefinition.validate(name: "\(name).metricDefinition")
        }

        private enum CodingKeys: String, CodingKey {
            case metricDefinition
        }
    }

    public struct OnlineAbConfig: AWSEncodableShape {
        /// The name of the variation that is to be the default variation that the other variations are compared to.
        public let controlTreatmentName: String?
        /// A set of key-value pairs. The keys are variation names, and the values are the portion of experiment traffic to be assigned to that variation. Specify the traffic portion in thousandths of a percent, so 20,000 for a variation would allocate 20% of the experiment traffic to that variation.
        public let treatmentWeights: [String: Int64]?

        public init(controlTreatmentName: String? = nil, treatmentWeights: [String: Int64]? = nil) {
            self.controlTreatmentName = controlTreatmentName
            self.treatmentWeights = treatmentWeights
        }

        public func validate(name: String) throws {
            try self.validate(self.controlTreatmentName, name: "controlTreatmentName", parent: name, max: 127)
            try self.validate(self.controlTreatmentName, name: "controlTreatmentName", parent: name, min: 1)
            try self.validate(self.controlTreatmentName, name: "controlTreatmentName", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.treatmentWeights?.forEach {
                try validate($0.key, name: "treatmentWeights.key", parent: name, max: 127)
                try validate($0.key, name: "treatmentWeights.key", parent: name, min: 1)
                try validate($0.key, name: "treatmentWeights.key", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
                try validate($0.value, name: "treatmentWeights[\"\($0.key)\"]", parent: name, max: 100_000)
                try validate($0.value, name: "treatmentWeights[\"\($0.key)\"]", parent: name, min: 0)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case controlTreatmentName
            case treatmentWeights
        }
    }

    public struct OnlineAbDefinition: AWSDecodableShape {
        /// The name of the variation that is the default variation that the other variations are compared to.
        public let controlTreatmentName: String?
        /// A set of key-value pairs.  The keys are variation names, and the values are the portion of experiment traffic to be assigned to that variation. The traffic portion is specified in thousandths of a percent, so 20,000 for a variation would allocate 20% of the experiment traffic to that variation.
        public let treatmentWeights: [String: Int64]?

        public init(controlTreatmentName: String? = nil, treatmentWeights: [String: Int64]? = nil) {
            self.controlTreatmentName = controlTreatmentName
            self.treatmentWeights = treatmentWeights
        }

        private enum CodingKeys: String, CodingKey {
            case controlTreatmentName
            case treatmentWeights
        }
    }

    public struct Project: AWSDecodableShape {
        /// The number of ongoing experiments currently in the project.
        public let activeExperimentCount: Int64?
        /// The number of ongoing launches currently in the project.
        public let activeLaunchCount: Int64?
        /// This structure defines the configuration of how your application  integrates with AppConfig to run client-side evaluation.
        public let appConfigResource: ProjectAppConfigResource?
        /// The name or ARN of the project.
        public let arn: String
        /// The date and time that the project is created.
        public let createdTime: Date
        /// A structure that contains information about where Evidently is to store evaluation events for longer term storage.
        public let dataDelivery: ProjectDataDelivery?
        /// The user-entered description of the project.
        public let description: String?
        /// The number of experiments currently in the project. This includes all experiments that have been created and not deleted, whether they are ongoing or not.
        public let experimentCount: Int64?
        /// The number of features currently in the project.
        public let featureCount: Int64?
        /// The date and time that the project was most recently updated.
        public let lastUpdatedTime: Date
        /// The number of launches currently in the project. This includes all launches that have been created and not deleted, whether they are ongoing or not.
        public let launchCount: Int64?
        /// The name of the project.
        public let name: String
        /// The current state of the project.
        public let status: ProjectStatus
        /// The list of tag keys and values associated with this project.
        public let tags: [String: String]?

        public init(activeExperimentCount: Int64? = nil, activeLaunchCount: Int64? = nil, appConfigResource: ProjectAppConfigResource? = nil, arn: String, createdTime: Date, dataDelivery: ProjectDataDelivery? = nil, description: String? = nil, experimentCount: Int64? = nil, featureCount: Int64? = nil, lastUpdatedTime: Date, launchCount: Int64? = nil, name: String, status: ProjectStatus, tags: [String: String]? = nil) {
            self.activeExperimentCount = activeExperimentCount
            self.activeLaunchCount = activeLaunchCount
            self.appConfigResource = appConfigResource
            self.arn = arn
            self.createdTime = createdTime
            self.dataDelivery = dataDelivery
            self.description = description
            self.experimentCount = experimentCount
            self.featureCount = featureCount
            self.lastUpdatedTime = lastUpdatedTime
            self.launchCount = launchCount
            self.name = name
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case activeExperimentCount
            case activeLaunchCount
            case appConfigResource
            case arn
            case createdTime
            case dataDelivery
            case description
            case experimentCount
            case featureCount
            case lastUpdatedTime
            case launchCount
            case name
            case status
            case tags
        }
    }

    public struct ProjectAppConfigResource: AWSDecodableShape {
        /// The ID of the AppConfig application to use for client-side evaluation.
        public let applicationId: String
        /// The ID of the AppConfig profile to use for client-side evaluation.
        public let configurationProfileId: String
        /// The ID of the AppConfig environment to use for client-side evaluation. This must be an  environment that is within the application that you specify for applicationId.
        public let environmentId: String

        public init(applicationId: String, configurationProfileId: String, environmentId: String) {
            self.applicationId = applicationId
            self.configurationProfileId = configurationProfileId
            self.environmentId = environmentId
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId
            case configurationProfileId
            case environmentId
        }
    }

    public struct ProjectAppConfigResourceConfig: AWSEncodableShape {
        /// The ID of the AppConfig application to use for client-side evaluation.
        public let applicationId: String?
        /// The ID of the AppConfig environment to use for client-side evaluation. This must be an  environment that is within the application that you specify for applicationId.
        public let environmentId: String?

        public init(applicationId: String? = nil, environmentId: String? = nil) {
            self.applicationId = applicationId
            self.environmentId = environmentId
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "[a-z0-9]{4,7}")
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "[a-z0-9]{4,7}")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId
            case environmentId
        }
    }

    public struct ProjectDataDelivery: AWSDecodableShape {
        /// If the project stores evaluation events in CloudWatch Logs, this structure stores the log group name.
        public let cloudWatchLogs: CloudWatchLogsDestination?
        /// If the project stores evaluation events in an Amazon S3 bucket, this structure stores the bucket name and bucket prefix.
        public let s3Destination: S3Destination?

        public init(cloudWatchLogs: CloudWatchLogsDestination? = nil, s3Destination: S3Destination? = nil) {
            self.cloudWatchLogs = cloudWatchLogs
            self.s3Destination = s3Destination
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogs
            case s3Destination
        }
    }

    public struct ProjectDataDeliveryConfig: AWSEncodableShape {
        /// If the project stores evaluation events in CloudWatch Logs, this structure stores the log group name.
        public let cloudWatchLogs: CloudWatchLogsDestinationConfig?
        /// If the project stores evaluation events in an Amazon S3 bucket, this structure stores the bucket name and bucket prefix.
        public let s3Destination: S3DestinationConfig?

        public init(cloudWatchLogs: CloudWatchLogsDestinationConfig? = nil, s3Destination: S3DestinationConfig? = nil) {
            self.cloudWatchLogs = cloudWatchLogs
            self.s3Destination = s3Destination
        }

        public func validate(name: String) throws {
            try self.cloudWatchLogs?.validate(name: "\(name).cloudWatchLogs")
            try self.s3Destination?.validate(name: "\(name).s3Destination")
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogs
            case s3Destination
        }
    }

    public struct ProjectSummary: AWSDecodableShape {
        /// The number of experiments currently in the project.
        public let activeExperimentCount: Int64?
        /// The number of ongoing launches currently in the project.
        public let activeLaunchCount: Int64?
        /// The name or ARN of the project.
        public let arn: String
        /// The date and time that the project is created.
        public let createdTime: Date
        /// The description of the project.
        public let description: String?
        /// The number of experiments currently in the project.
        public let experimentCount: Int64?
        /// The number of features currently in the project.
        public let featureCount: Int64?
        /// The date and time that the project was most recently updated.
        public let lastUpdatedTime: Date
        /// The number of launches currently in the project, including launches that are ongoing, completed, and not started yet.
        public let launchCount: Int64?
        /// The name of the project.
        public let name: String
        /// The current state of the project.
        public let status: ProjectStatus
        /// The list of tag keys and values associated with this project.
        public let tags: [String: String]?

        public init(activeExperimentCount: Int64? = nil, activeLaunchCount: Int64? = nil, arn: String, createdTime: Date, description: String? = nil, experimentCount: Int64? = nil, featureCount: Int64? = nil, lastUpdatedTime: Date, launchCount: Int64? = nil, name: String, status: ProjectStatus, tags: [String: String]? = nil) {
            self.activeExperimentCount = activeExperimentCount
            self.activeLaunchCount = activeLaunchCount
            self.arn = arn
            self.createdTime = createdTime
            self.description = description
            self.experimentCount = experimentCount
            self.featureCount = featureCount
            self.lastUpdatedTime = lastUpdatedTime
            self.launchCount = launchCount
            self.name = name
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case activeExperimentCount
            case activeLaunchCount
            case arn
            case createdTime
            case description
            case experimentCount
            case featureCount
            case lastUpdatedTime
            case launchCount
            case name
            case status
            case tags
        }
    }

    public struct PutProjectEventsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An array of event structures that contain the performance data that is being sent to Evidently.
        public let events: [Event]
        /// The name or ARN of the project to write the events to.
        public let project: String

        public init(events: [Event], project: String) {
            self.events = events
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.events, name: "events", parent: name, max: 50)
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: String, CodingKey {
            case events
        }
    }

    public struct PutProjectEventsResponse: AWSDecodableShape {
        /// A structure that contains Evidently's response to the sent events, including an event ID and  error codes, if any.
        public let eventResults: [PutProjectEventsResultEntry]?
        /// The number of events in the operation that could not be used by Evidently.
        public let failedEventCount: Int?

        public init(eventResults: [PutProjectEventsResultEntry]? = nil, failedEventCount: Int? = nil) {
            self.eventResults = eventResults
            self.failedEventCount = failedEventCount
        }

        private enum CodingKeys: String, CodingKey {
            case eventResults
            case failedEventCount
        }
    }

    public struct PutProjectEventsResultEntry: AWSDecodableShape {
        /// If the PutProjectEvents operation has an error, the error code is returned here.
        public let errorCode: String?
        /// If the PutProjectEvents operation has an error, the error message is returned here.
        public let errorMessage: String?
        /// A unique ID assigned to this PutProjectEvents operation.
        public let eventId: String?

        public init(errorCode: String? = nil, errorMessage: String? = nil, eventId: String? = nil) {
            self.errorCode = errorCode
            self.errorMessage = errorMessage
            self.eventId = eventId
        }

        private enum CodingKeys: String, CodingKey {
            case errorCode
            case errorMessage
            case eventId
        }
    }

    public struct RefResource: AWSDecodableShape {
        /// The ARN of the experiment or launch.
        public let arn: String?
        /// The day and time that this experiment or launch ended.
        public let endTime: String?
        /// The day and time that this experiment or launch was most recently updated.
        public let lastUpdatedOn: String?
        /// The name of the experiment or launch.
        public let name: String
        /// The day and time that this experiment or launch started.
        public let startTime: String?
        /// The status of the experiment or launch.
        public let status: String?
        /// Specifies whether the resource that this structure contains information about is an experiment or a launch.
        public let type: String

        public init(arn: String? = nil, endTime: String? = nil, lastUpdatedOn: String? = nil, name: String, startTime: String? = nil, status: String? = nil, type: String) {
            self.arn = arn
            self.endTime = endTime
            self.lastUpdatedOn = lastUpdatedOn
            self.name = name
            self.startTime = startTime
            self.status = status
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case endTime
            case lastUpdatedOn
            case name
            case startTime
            case status
            case type
        }
    }

    public struct S3Destination: AWSDecodableShape {
        /// The name of the bucket in which Evidently stores evaluation events.
        public let bucket: String?
        /// The bucket prefix in which Evidently stores evaluation events.
        public let prefix: String?

        public init(bucket: String? = nil, prefix: String? = nil) {
            self.bucket = bucket
            self.prefix = prefix
        }

        private enum CodingKeys: String, CodingKey {
            case bucket
            case prefix
        }
    }

    public struct S3DestinationConfig: AWSEncodableShape {
        /// The name of the bucket in which Evidently stores evaluation events.
        public let bucket: String?
        /// The bucket prefix in which Evidently stores evaluation events.
        public let prefix: String?

        public init(bucket: String? = nil, prefix: String? = nil) {
            self.bucket = bucket
            self.prefix = prefix
        }

        public func validate(name: String) throws {
            try self.validate(self.bucket, name: "bucket", parent: name, max: 63)
            try self.validate(self.bucket, name: "bucket", parent: name, min: 3)
            try self.validate(self.bucket, name: "bucket", parent: name, pattern: "^[a-z0-9][-a-z0-9]*[a-z0-9]$")
            try self.validate(self.prefix, name: "prefix", parent: name, max: 1024)
            try self.validate(self.prefix, name: "prefix", parent: name, min: 1)
            try self.validate(self.prefix, name: "prefix", parent: name, pattern: "^[-a-zA-Z0-9!_.*'()/]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case bucket
            case prefix
        }
    }

    public struct ScheduledSplit: AWSDecodableShape {
        /// The traffic allocation percentages among the feature variations during one step of a launch. This is a set of key-value pairs.   The keys are variation names. The values represent the percentage of traffic to allocate to that variation during this step. The values is expressed in thousandths of a percent, so assigning a weight of 50000 assigns 50% of traffic to that variation. If the sum of the weights for all the variations in a segment override does not add up to 100,000,  then the remaining traffic that matches this segment is not assigned by this segment override, and instead moves on to the next segment override or the default traffic split.
        public let groupWeights: [String: Int64]?
        /// Use this parameter to specify different traffic splits for one or more audience segments.  A segment is a portion of your audience that share one or more characteristics. Examples could be Chrome browser users,  users in Europe, or Firefox browser users in Europe who also fit other criteria that your application collects, such as age. This parameter is an array of up to six segment override objects. Each of these objects specifies a segment that you have already created, and defines the traffic split for that segment.
        public let segmentOverrides: [SegmentOverride]?
        /// The date and time that this step of the launch starts.
        public let startTime: Date

        public init(groupWeights: [String: Int64]? = nil, segmentOverrides: [SegmentOverride]? = nil, startTime: Date) {
            self.groupWeights = groupWeights
            self.segmentOverrides = segmentOverrides
            self.startTime = startTime
        }

        private enum CodingKeys: String, CodingKey {
            case groupWeights
            case segmentOverrides
            case startTime
        }
    }

    public struct ScheduledSplitConfig: AWSEncodableShape {
        /// The traffic allocation percentages among the feature variations during one step of a launch. This is a set of key-value pairs. The keys are variation names. The values represent the percentage of traffic to allocate to that variation during this step.  The values is expressed in thousandths of a percent, so assigning a weight of 50000 assigns 50% of traffic to that variation. If the sum of the weights for all the variations in a segment override does not add up to 100,000,  then the remaining traffic that matches this segment is not assigned by this segment override, and instead moves on to the next segment override or the default traffic split.
        public let groupWeights: [String: Int64]
        /// Use this parameter to specify different traffic splits for one or more audience segments.  A segment is a portion of your audience that share one or more characteristics. Examples could be Chrome browser users,  users in Europe, or Firefox browser users in Europe who also fit other criteria that your application collects, such as age. This parameter is an array of up to six segment override objects. Each of these objects specifies a segment that you have already created, and defines the traffic split for that segment.
        public let segmentOverrides: [SegmentOverride]?
        /// The date and time that this step of the launch starts.
        public let startTime: Date

        public init(groupWeights: [String: Int64], segmentOverrides: [SegmentOverride]? = nil, startTime: Date) {
            self.groupWeights = groupWeights
            self.segmentOverrides = segmentOverrides
            self.startTime = startTime
        }

        public func validate(name: String) throws {
            try self.groupWeights.forEach {
                try validate($0.key, name: "groupWeights.key", parent: name, max: 127)
                try validate($0.key, name: "groupWeights.key", parent: name, min: 1)
                try validate($0.key, name: "groupWeights.key", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
                try validate($0.value, name: "groupWeights[\"\($0.key)\"]", parent: name, max: 100_000)
                try validate($0.value, name: "groupWeights[\"\($0.key)\"]", parent: name, min: 0)
            }
            try self.validate(self.groupWeights, name: "groupWeights", parent: name, max: 5)
            try self.segmentOverrides?.forEach {
                try $0.validate(name: "\(name).segmentOverrides[]")
            }
            try self.validate(self.segmentOverrides, name: "segmentOverrides", parent: name, max: 6)
        }

        private enum CodingKeys: String, CodingKey {
            case groupWeights
            case segmentOverrides
            case startTime
        }
    }

    public struct ScheduledSplitsLaunchConfig: AWSEncodableShape {
        /// An array of structures that define the traffic allocation percentages among the feature variations during each step of the launch. This also defines the start time of each step.
        public let steps: [ScheduledSplitConfig]

        public init(steps: [ScheduledSplitConfig]) {
            self.steps = steps
        }

        public func validate(name: String) throws {
            try self.steps.forEach {
                try $0.validate(name: "\(name).steps[]")
            }
            try self.validate(self.steps, name: "steps", parent: name, max: 6)
            try self.validate(self.steps, name: "steps", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case steps
        }
    }

    public struct ScheduledSplitsLaunchDefinition: AWSDecodableShape {
        /// An array of structures that define the traffic allocation percentages among the feature variations during each step of the launch. This also defines the start time of each step.
        public let steps: [ScheduledSplit]?

        public init(steps: [ScheduledSplit]? = nil) {
            self.steps = steps
        }

        private enum CodingKeys: String, CodingKey {
            case steps
        }
    }

    public struct Segment: AWSDecodableShape {
        /// The ARN of the segment.
        public let arn: String
        /// The date and time that this segment was created.
        public let createdTime: Date
        /// The customer-created description for this segment.
        public let description: String?
        /// The number of experiments that this segment is used in. This count includes all current experiments, not just those that are currently running.
        public let experimentCount: Int64?
        /// The date and time that this segment was most recently updated.
        public let lastUpdatedTime: Date
        /// The number of launches that this segment is used in. This count includes all current launches, not just those that are currently running.
        public let launchCount: Int64?
        /// The name of the segment.
        public let name: String
        /// The pattern that defines the attributes to use to evalute whether a user session will be in the segment.  For more information about the pattern syntax, see  Segment rule pattern syntax.
        public let pattern: String
        /// The list of tag keys and values associated with this launch.
        public let tags: [String: String]?

        public init(arn: String, createdTime: Date, description: String? = nil, experimentCount: Int64? = nil, lastUpdatedTime: Date, launchCount: Int64? = nil, name: String, pattern: String, tags: [String: String]? = nil) {
            self.arn = arn
            self.createdTime = createdTime
            self.description = description
            self.experimentCount = experimentCount
            self.lastUpdatedTime = lastUpdatedTime
            self.launchCount = launchCount
            self.name = name
            self.pattern = pattern
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdTime
            case description
            case experimentCount
            case lastUpdatedTime
            case launchCount
            case name
            case pattern
            case tags
        }
    }

    public struct SegmentOverride: AWSEncodableShape & AWSDecodableShape {
        /// A number indicating the order to use to evaluate segment overrides, if there are more than one. Segment overrides with lower numbers are evaluated first.
        public let evaluationOrder: Int64
        /// The ARN of the segment to use.
        public let segment: String
        /// The traffic allocation percentages among the feature variations to assign to this  segment. This is a set of key-value pairs.   The keys are variation names. The values represent the amount of traffic to allocate to that variation for this segment. This is expressed in thousandths of a percent, so a weight of 50000 represents 50% of traffic.
        public let weights: [String: Int64]

        public init(evaluationOrder: Int64, segment: String, weights: [String: Int64]) {
            self.evaluationOrder = evaluationOrder
            self.segment = segment
            self.weights = weights
        }

        public func validate(name: String) throws {
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
            try self.weights.forEach {
                try validate($0.key, name: "weights.key", parent: name, max: 127)
                try validate($0.key, name: "weights.key", parent: name, min: 1)
                try validate($0.key, name: "weights.key", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
                try validate($0.value, name: "weights[\"\($0.key)\"]", parent: name, max: 100_000)
                try validate($0.value, name: "weights[\"\($0.key)\"]", parent: name, min: 0)
            }
            try self.validate(self.weights, name: "weights", parent: name, max: 5)
        }

        private enum CodingKeys: String, CodingKey {
            case evaluationOrder
            case segment
            case weights
        }
    }

    public struct StartExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The date and time to end the experiment. This must be no more than 30 days after the experiment starts.
        public let analysisCompleteTime: Date
        /// The name of the experiment to start.
        public let experiment: String
        /// The name or ARN of the project that contains the experiment to start.
        public let project: String

        public init(analysisCompleteTime: Date, experiment: String, project: String) {
            self.analysisCompleteTime = analysisCompleteTime
            self.experiment = experiment
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: String, CodingKey {
            case analysisCompleteTime
        }
    }

    public struct StartExperimentResponse: AWSDecodableShape {
        /// A timestamp that indicates when the experiment started.
        public let startedTime: Date?

        public init(startedTime: Date? = nil) {
            self.startedTime = startedTime
        }

        private enum CodingKeys: String, CodingKey {
            case startedTime
        }
    }

    public struct StartLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "launch", location: .uri("launch")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// The name of the launch to start.
        public let launch: String
        /// The name or ARN of the project that contains the launch to start.
        public let project: String

        public init(launch: String, project: String) {
            self.launch = launch
            self.project = project
        }

        public func validate(name: String) throws {
            try self.validate(self.launch, name: "launch", parent: name, max: 127)
            try self.validate(self.launch, name: "launch", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct StartLaunchResponse: AWSDecodableShape {
        /// A structure that contains information about the launch that was started.
        public let launch: Launch

        public init(launch: Launch) {
            self.launch = launch
        }

        private enum CodingKeys: String, CodingKey {
            case launch
        }
    }

    public struct StopExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// Specify whether the experiment is to be considered COMPLETED or  CANCELLED after it stops.
        public let desiredState: ExperimentStopDesiredState?
        /// The name of the experiment to stop.
        public let experiment: String
        /// The name or ARN of the project that contains the experiment to stop.
        public let project: String
        /// A string that describes why you are stopping the experiment.
        public let reason: String?

        public init(desiredState: ExperimentStopDesiredState? = nil, experiment: String, project: String, reason: String? = nil) {
            self.desiredState = desiredState
            self.experiment = experiment
            self.project = project
            self.reason = reason
        }

        public func validate(name: String) throws {
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.reason, name: "reason", parent: name, max: 160)
            try self.validate(self.reason, name: "reason", parent: name, pattern: ".*")
        }

        private enum CodingKeys: String, CodingKey {
            case desiredState
            case reason
        }
    }

    public struct StopExperimentResponse: AWSDecodableShape {
        /// The date and time that the experiment stopped.
        public let endedTime: Date?

        public init(endedTime: Date? = nil) {
            self.endedTime = endedTime
        }

        private enum CodingKeys: String, CodingKey {
            case endedTime
        }
    }

    public struct StopLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "launch", location: .uri("launch")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// Specify whether to consider the launch as COMPLETED or CANCELLED after it stops.
        public let desiredState: LaunchStopDesiredState?
        /// The name of the launch to stop.
        public let launch: String
        /// The name or ARN of the project that contains the launch that you want to stop.
        public let project: String
        /// A string that describes why you are stopping the launch.
        public let reason: String?

        public init(desiredState: LaunchStopDesiredState? = nil, launch: String, project: String, reason: String? = nil) {
            self.desiredState = desiredState
            self.launch = launch
            self.project = project
            self.reason = reason
        }

        public func validate(name: String) throws {
            try self.validate(self.launch, name: "launch", parent: name, max: 127)
            try self.validate(self.launch, name: "launch", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.reason, name: "reason", parent: name, max: 160)
            try self.validate(self.reason, name: "reason", parent: name, pattern: ".*")
        }

        private enum CodingKeys: String, CodingKey {
            case desiredState
            case reason
        }
    }

    public struct StopLaunchResponse: AWSDecodableShape {
        /// The date and time that the launch stopped.
        public let endedTime: Date?

        public init(endedTime: Date? = nil) {
            self.endedTime = endedTime
        }

        private enum CodingKeys: String, CodingKey {
            case endedTime
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// The ARN of the CloudWatch Evidently resource that you're adding tags to.
        public let resourceArn: String
        /// The list of key-value pairs to associate with the resource.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct TestSegmentPatternRequest: AWSEncodableShape {
        /// The pattern to test.
        public let pattern: String
        /// A sample evaluationContext JSON block to test against the specified pattern.
        public let payload: String

        public init(pattern: String, payload: String) {
            self.pattern = pattern
            self.payload = payload
        }

        public func validate(name: String) throws {
            try self.validate(self.pattern, name: "pattern", parent: name, max: 1024)
            try self.validate(self.pattern, name: "pattern", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case pattern
            case payload
        }
    }

    public struct TestSegmentPatternResponse: AWSDecodableShape {
        /// Returns true if the pattern matches the payload.
        public let match: Bool

        public init(match: Bool) {
            self.match = match
        }

        private enum CodingKeys: String, CodingKey {
            case match
        }
    }

    public struct Treatment: AWSDecodableShape {
        /// The description of the treatment.
        public let description: String?
        /// The feature variation used for this treatment. This is a key-value pair. The key is the feature name, and the value is the variation name.
        public let featureVariations: [String: String]?
        /// The name of this treatment.
        public let name: String

        public init(description: String? = nil, featureVariations: [String: String]? = nil, name: String) {
            self.description = description
            self.featureVariations = featureVariations
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case featureVariations
            case name
        }
    }

    public struct TreatmentConfig: AWSEncodableShape {
        /// A description for this treatment.
        public let description: String?
        /// The feature that this experiment is testing.
        public let feature: String
        /// A name for this treatment.
        public let name: String
        /// The name of the variation to use as this treatment in the experiment.
        public let variation: String

        public init(description: String? = nil, feature: String, name: String, variation: String) {
            self.description = description
            self.feature = feature
            self.name = name
            self.variation = variation
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.variation, name: "variation", parent: name, max: 127)
            try self.validate(self.variation, name: "variation", parent: name, min: 1)
            try self.validate(self.variation, name: "variation", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case feature
            case name
            case variation
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        /// The ARN of the CloudWatch Evidently resource that you're removing tags from.
        public let resourceArn: String
        /// The list of tag keys to remove from the resource.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateExperimentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "experiment", location: .uri("experiment")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An optional description of the experiment.
        public let description: String?
        /// The name of the experiment to update.
        public let experiment: String
        /// An array of structures that defines the metrics used for the experiment, and whether a higher or lower value for each metric is the goal.
        public let metricGoals: [MetricGoalConfig]?
        /// A structure that contains the configuration of which variation o use as the "control" version. The "control" version is used for comparison with other variations. This structure also specifies how much experiment traffic is allocated to each variation.
        public let onlineAbConfig: OnlineAbConfig?
        /// The name or ARN of the project that contains the experiment that you want to update.
        public let project: String
        /// When Evidently assigns a particular user session to an experiment, it must use a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt. If you omit randomizationSalt, Evidently uses the experiment name as the randomizationSalt.
        public let randomizationSalt: String?
        /// Removes a segment from being used in an experiment. You can't use this parameter if the experiment is currently running.
        public let removeSegment: Bool?
        /// The portion of the available audience that you want to allocate to this experiment, in thousandths of a percent. The available audience is the total audience minus the audience that you have allocated to overrides or current launches of this feature. This is represented in thousandths of a percent. For example, specify 20,000 to allocate 20% of the available audience.
        public let samplingRate: Int64?
        /// Adds an audience segment to an experiment. When a segment is used in an experiment, only user sessions that match the segment pattern are used in the experiment. You can't use this parameter if the  experiment is currently running.
        public let segment: String?
        /// An array of structures that define the variations being tested in the experiment.
        public let treatments: [TreatmentConfig]?

        public init(description: String? = nil, experiment: String, metricGoals: [MetricGoalConfig]? = nil, onlineAbConfig: OnlineAbConfig? = nil, project: String, randomizationSalt: String? = nil, removeSegment: Bool? = nil, samplingRate: Int64? = nil, segment: String? = nil, treatments: [TreatmentConfig]? = nil) {
            self.description = description
            self.experiment = experiment
            self.metricGoals = metricGoals
            self.onlineAbConfig = onlineAbConfig
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.removeSegment = removeSegment
            self.samplingRate = samplingRate
            self.segment = segment
            self.treatments = treatments
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.experiment, name: "experiment", parent: name, max: 127)
            try self.validate(self.experiment, name: "experiment", parent: name, min: 1)
            try self.validate(self.experiment, name: "experiment", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.metricGoals?.forEach {
                try $0.validate(name: "\(name).metricGoals[]")
            }
            try self.validate(self.metricGoals, name: "metricGoals", parent: name, max: 3)
            try self.validate(self.metricGoals, name: "metricGoals", parent: name, min: 1)
            try self.onlineAbConfig?.validate(name: "\(name).onlineAbConfig")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, max: 127)
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, pattern: ".*")
            try self.validate(self.samplingRate, name: "samplingRate", parent: name, max: 100_000)
            try self.validate(self.samplingRate, name: "samplingRate", parent: name, min: 0)
            try self.validate(self.segment, name: "segment", parent: name, max: 2048)
            try self.validate(self.segment, name: "segment", parent: name, pattern: "(^[-a-zA-Z0-9._]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:segment/[-a-zA-Z0-9._]*)")
            try self.treatments?.forEach {
                try $0.validate(name: "\(name).treatments[]")
            }
            try self.validate(self.treatments, name: "treatments", parent: name, max: 5)
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case metricGoals
            case onlineAbConfig
            case randomizationSalt
            case removeSegment
            case samplingRate
            case segment
            case treatments
        }
    }

    public struct UpdateExperimentResponse: AWSDecodableShape {
        /// A structure containing the configuration details of the experiment that was updated.
        public let experiment: Experiment

        public init(experiment: Experiment) {
            self.experiment = experiment
        }

        private enum CodingKeys: String, CodingKey {
            case experiment
        }
    }

    public struct UpdateFeatureRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "feature", location: .uri("feature")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// To update variation configurations for this feature, or add new ones, specify this structure. In this array, include any variations that you want to add or update. If the array includes a variation name that already exists for this feature, it is updated. If it includes a new variation name, it is added as a new variation.
        public let addOrUpdateVariations: [VariationConfig]?
        /// The name of the variation to use as the default variation. The default variation is served to users who are not allocated to any ongoing launches or experiments of this feature.
        public let defaultVariation: String?
        /// An optional description of the feature.
        public let description: String?
        /// Specified users that should always be served a specific variation of a feature. Each user is specified by a key-value pair . For each key, specify a user by entering their user ID, account ID, or some other identifier. For the value, specify the name of the variation that they are to be served.
        public let entityOverrides: [String: String]?
        /// Specify ALL_RULES to activate the traffic allocation specified by any ongoing launches or experiments. Specify DEFAULT_VARIATION to serve the default variation to all users instead.
        public let evaluationStrategy: FeatureEvaluationStrategy?
        /// The name of the feature to be updated.
        public let feature: String
        /// The name or ARN of the project that contains the feature to be updated.
        public let project: String
        /// Removes a variation from the feature. If the variation you specify doesn't exist, then this  makes no change and does not report an error. This operation fails if you try to remove a variation that is part of an  ongoing launch or experiment.
        public let removeVariations: [String]?

        public init(addOrUpdateVariations: [VariationConfig]? = nil, defaultVariation: String? = nil, description: String? = nil, entityOverrides: [String: String]? = nil, evaluationStrategy: FeatureEvaluationStrategy? = nil, feature: String, project: String, removeVariations: [String]? = nil) {
            self.addOrUpdateVariations = addOrUpdateVariations
            self.defaultVariation = defaultVariation
            self.description = description
            self.entityOverrides = entityOverrides
            self.evaluationStrategy = evaluationStrategy
            self.feature = feature
            self.project = project
            self.removeVariations = removeVariations
        }

        public func validate(name: String) throws {
            try self.addOrUpdateVariations?.forEach {
                try $0.validate(name: "\(name).addOrUpdateVariations[]")
            }
            try self.validate(self.addOrUpdateVariations, name: "addOrUpdateVariations", parent: name, max: 5)
            try self.validate(self.addOrUpdateVariations, name: "addOrUpdateVariations", parent: name, min: 1)
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, max: 127)
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, min: 1)
            try self.validate(self.defaultVariation, name: "defaultVariation", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.entityOverrides?.forEach {
                try validate($0.key, name: "entityOverrides.key", parent: name, max: 512)
                try validate($0.key, name: "entityOverrides.key", parent: name, min: 1)
                try validate($0.key, name: "entityOverrides.key", parent: name, pattern: ".*")
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, max: 127)
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "entityOverrides[\"\($0.key)\"]", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            }
            try self.validate(self.entityOverrides, name: "entityOverrides", parent: name, max: 20)
            try self.validate(self.feature, name: "feature", parent: name, max: 127)
            try self.validate(self.feature, name: "feature", parent: name, min: 1)
            try self.validate(self.feature, name: "feature", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.removeVariations?.forEach {
                try validate($0, name: "removeVariations[]", parent: name, max: 127)
                try validate($0, name: "removeVariations[]", parent: name, min: 1)
                try validate($0, name: "removeVariations[]", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            }
            try self.validate(self.removeVariations, name: "removeVariations", parent: name, max: 5)
        }

        private enum CodingKeys: String, CodingKey {
            case addOrUpdateVariations
            case defaultVariation
            case description
            case entityOverrides
            case evaluationStrategy
            case removeVariations
        }
    }

    public struct UpdateFeatureResponse: AWSDecodableShape {
        /// A structure that contains information about the updated feature.
        public let feature: Feature

        public init(feature: Feature) {
            self.feature = feature
        }

        private enum CodingKeys: String, CodingKey {
            case feature
        }
    }

    public struct UpdateLaunchRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "launch", location: .uri("launch")),
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// An optional description for the launch.
        public let description: String?
        /// An array of structures that contains the feature and variations that are to be used for the launch.
        public let groups: [LaunchGroupConfig]?
        /// The name of the launch that is to be updated.
        public let launch: String
        /// An array of structures that define the metrics that will be used to monitor  the launch performance.
        public let metricMonitors: [MetricMonitorConfig]?
        /// The name or ARN of the project that contains the launch that you want to update.
        public let project: String
        /// When Evidently assigns a particular user session to a launch, it must use a randomization ID to determine which variation the user session is served. This randomization ID is a combination of the entity ID and randomizationSalt. If you omit randomizationSalt, Evidently uses the launch name as the randomizationSalt.
        public let randomizationSalt: String?
        /// An array of structures that define the traffic allocation percentages among the feature variations during each step of the launch.
        public let scheduledSplitsConfig: ScheduledSplitsLaunchConfig?

        public init(description: String? = nil, groups: [LaunchGroupConfig]? = nil, launch: String, metricMonitors: [MetricMonitorConfig]? = nil, project: String, randomizationSalt: String? = nil, scheduledSplitsConfig: ScheduledSplitsLaunchConfig? = nil) {
            self.description = description
            self.groups = groups
            self.launch = launch
            self.metricMonitors = metricMonitors
            self.project = project
            self.randomizationSalt = randomizationSalt
            self.scheduledSplitsConfig = scheduledSplitsConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.groups?.forEach {
                try $0.validate(name: "\(name).groups[]")
            }
            try self.validate(self.groups, name: "groups", parent: name, max: 5)
            try self.validate(self.groups, name: "groups", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, max: 127)
            try self.validate(self.launch, name: "launch", parent: name, min: 1)
            try self.validate(self.launch, name: "launch", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
            try self.metricMonitors?.forEach {
                try $0.validate(name: "\(name).metricMonitors[]")
            }
            try self.validate(self.metricMonitors, name: "metricMonitors", parent: name, max: 3)
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, max: 127)
            try self.validate(self.randomizationSalt, name: "randomizationSalt", parent: name, pattern: ".*")
            try self.scheduledSplitsConfig?.validate(name: "\(name).scheduledSplitsConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case description
            case groups
            case metricMonitors
            case randomizationSalt
            case scheduledSplitsConfig
        }
    }

    public struct UpdateLaunchResponse: AWSDecodableShape {
        /// A structure that contains the new configuration of the launch that was updated.
        public let launch: Launch

        public init(launch: Launch) {
            self.launch = launch
        }

        private enum CodingKeys: String, CodingKey {
            case launch
        }
    }

    public struct UpdateProjectDataDeliveryRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// A structure containing the CloudWatch Logs log group where you want to store evaluation events.
        public let cloudWatchLogs: CloudWatchLogsDestinationConfig?
        /// The name or ARN of the project that you want to modify the data storage options for.
        public let project: String
        /// A structure containing the S3 bucket name and bucket prefix where you want to store evaluation events.
        public let s3Destination: S3DestinationConfig?

        public init(cloudWatchLogs: CloudWatchLogsDestinationConfig? = nil, project: String, s3Destination: S3DestinationConfig? = nil) {
            self.cloudWatchLogs = cloudWatchLogs
            self.project = project
            self.s3Destination = s3Destination
        }

        public func validate(name: String) throws {
            try self.cloudWatchLogs?.validate(name: "\(name).cloudWatchLogs")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
            try self.s3Destination?.validate(name: "\(name).s3Destination")
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogs
            case s3Destination
        }
    }

    public struct UpdateProjectDataDeliveryResponse: AWSDecodableShape {
        /// A structure containing details about the project that you updated.
        public let project: Project

        public init(project: Project) {
            self.project = project
        }

        private enum CodingKeys: String, CodingKey {
            case project
        }
    }

    public struct UpdateProjectRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "project", location: .uri("project"))
        ]

        /// Use this parameter if the project will use client-side evaluation powered by AppConfig. Client-side evaluation allows your application to assign variations to user sessions locally instead of by calling the EvaluateFeature operation. This  mitigates the latency and availability risks that come with an API call. allows you to This parameter is a structure that contains information about the AppConfig application that will be used for client-side evaluation.
        public let appConfigResource: ProjectAppConfigResourceConfig?
        /// An optional description of the project.
        public let description: String?
        /// The name or ARN of the project to update.
        public let project: String

        public init(appConfigResource: ProjectAppConfigResourceConfig? = nil, description: String? = nil, project: String) {
            self.appConfigResource = appConfigResource
            self.description = description
            self.project = project
        }

        public func validate(name: String) throws {
            try self.appConfigResource?.validate(name: "\(name).appConfigResource")
            try self.validate(self.description, name: "description", parent: name, max: 160)
            try self.validate(self.description, name: "description", parent: name, pattern: ".*")
            try self.validate(self.project, name: "project", parent: name, max: 2048)
            try self.validate(self.project, name: "project", parent: name, pattern: "(^[a-zA-Z0-9._-]*$)|(arn:[^:]*:[^:]*:[^:]*:[^:]*:project/[a-zA-Z0-9._-]*)")
        }

        private enum CodingKeys: String, CodingKey {
            case appConfigResource
            case description
        }
    }

    public struct UpdateProjectResponse: AWSDecodableShape {
        /// A structure containing information about the updated project.
        public let project: Project

        public init(project: Project) {
            self.project = project
        }

        private enum CodingKeys: String, CodingKey {
            case project
        }
    }

    public struct Variation: AWSDecodableShape {
        /// The name of the variation.
        public let name: String?
        /// The value assigned to this variation.
        public let value: VariableValue?

        public init(name: String? = nil, value: VariableValue? = nil) {
            self.name = name
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case value
        }
    }

    public struct VariationConfig: AWSEncodableShape {
        /// The name of the variation.
        public let name: String
        /// The value assigned to this variation.
        public let value: VariableValue

        public init(name: String, value: VariableValue) {
            self.name = name
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 127)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[-a-zA-Z0-9._]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case value
        }
    }
}

// MARK: - Errors

/// Error enum for Evidently
public struct EvidentlyErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case serviceUnavailableException = "ServiceUnavailableException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Evidently
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient permissions to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// A resource was in an inconsistent state during an update or a deletion.
    public static var conflictException: Self { .init(.conflictException) }
    /// Unexpected error while processing the request. Retry the request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The request references a resource that does not exist.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request would cause a service quota to be exceeded.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The service was unavailable. Retry the request.
    public static var serviceUnavailableException: Self { .init(.serviceUnavailableException) }
    /// The request was denied because of request throttling. Retry the request.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The value of a parameter in the request caused an error.
    public static var validationException: Self { .init(.validationException) }
}

extension EvidentlyErrorType: Equatable {
    public static func == (lhs: EvidentlyErrorType, rhs: EvidentlyErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension EvidentlyErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
